﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.Xml.Serialization;
using System.Xml;
using System.IO;
using Microsoft.Win32;
//
namespace ClassBuilder
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        
        //ObservableCollection<prop> propslist = new ObservableCollection<prop>();
        plist propslist=new plist();
        public MainWindow()
        {
            InitializeComponent();
            
            propslist.Add(new prop("Public", "Property" + (propslist.pcount +1).ToString()  , "String", false, "P"));

            lstProps.DataContext = propslist;
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            propslist.Add(new prop("Public", "Property" + (propslist.pcount + 1).ToString(), "String", false, "P"));
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            propslist.RemoveAt(lstProps.SelectedIndex);
        }

        private void button4_Click(object sender, RoutedEventArgs e)
        {
            int i = 0;
            string classtext = "";

            classtext += "Public Class " + textBox1.Text + "\r\n";

            foreach (prop p in propslist) //Properties
            {
                if (p.propitem=="P")
                classtext += string.Format("Private _{0} as {1} \r\n", p.propname.ToLower(), p.proptype);
            }
            foreach (prop p in propslist) //Fields
            {
                if (p.propitem == "F")
                    classtext += string.Format("Private _{0} as {1} \r\n", p.propname.ToLower(), p.proptype);
            }


            foreach (prop p in propslist) 
                if (p.propitem=="P")
            {
                if (p.propreadonly == true)
                    classtext += string.Format("{0} ReadOnly Property {1} as {2}\r\n", p.propscope, p.propname, p.proptype);
                else
                    classtext += string.Format("{0} Property {1} as {2}\r\n", p.propscope, p.propname, p.proptype);


                classtext += string.Format("Get\r\n");
                classtext += string.Format("Return _{0}\r\n", p.propname.ToLower());
                classtext += string.Format("End Get\r\n");
                if (p.propreadonly != true)
                {
                    classtext += string.Format("Set(value as {0})\r\n", p.proptype);
                    classtext += string.Format("_{0}=value\r\n", p.propname.ToLower());
                    classtext += string.Format("End Set\r\n");
                }
                classtext += string.Format("End Property\r\n");
            }
            if (checkBox1.IsChecked == true) //Blank Constructor
            {
                classtext += string.Format("Public Sub New() \r\nEnd Sub\r\n");
            }
            if (checkBox2.IsChecked == true) //Full Constructor
            {
                classtext += string.Format("Public Sub New(");
                foreach (prop p in propslist)
                    if (p.propitem=="P")
                {
                    classtext += string.Format("__{0} as {1}", p.propname.ToLower(), p.proptype);
                    i = i + 1;
                    if (i < propslist.Count)
                    {
                        classtext += ",";
                    }
                }
                classtext += ")\r\n";
                foreach (prop p in propslist)
                    if (p.propitem == "P")
                {
                    classtext += string.Format("_{0} = __{1}\r\n", p.propname.ToLower(), p.propname.ToLower());
                }
                classtext += "End Sub\r\n";
            }
            foreach (prop p in propslist) //Methods
                if (p.propitem == "M")
                {
                    classtext += string.Format("{0} Sub {1} \r\nEnd Sub\r\n", p.propscope, p.propname);
                }

            classtext += "End Class \r\n";
            Clipboard.SetData(DataFormats.Text, (Object)classtext);
            textBox2.Text = classtext;
        }

        private void button3_Click(object sender, RoutedEventArgs e)
        {
            propslist.Add(new prop("Public", "Field" + (propslist.fcount + 1).ToString(), "String", false, "F"));
            
        }

        private void button6_Click(object sender, RoutedEventArgs e)
        {
            propslist.Add(new prop("Public", "Method" + (propslist.mcount + 1).ToString(), "String", false, "M"));
        }

        private void button5_Click(object sender, RoutedEventArgs e)
        {
            propslist.Clear();
        }

        private void lstProps_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count == 1)
                button2.IsEnabled = true;
            else
                button2.IsEnabled = false;

        }
        private void LoadMetaData(string filename)
        {
            plist pp = new plist();
            XmlTextReader xtr = new XmlTextReader(filename);
            XmlSerializer x = new XmlSerializer(propslist.GetType());
            pp = (plist)x.Deserialize(xtr, null);
            propslist.Clear();
            foreach (prop p in pp)
                propslist.Add(p);
            this.Title = "ClassBuilder " + filename;
        }

        private void SaveMetaData(string filename)
    {
         
            XmlTextWriter xtw = new XmlTextWriter(filename,null);
            XmlSerializer x = new XmlSerializer(propslist.GetType());
            x.Serialize(xtw,propslist);
            this.Title = "ClassBuilder  " + filename;
    }

       

       

        private void LoadMetaDataClick(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.DefaultExt=".xml";
            dlg.Filter = "XML Documents(.xml)|*.xml";
            Nullable<Boolean> result = dlg.ShowDialog();
            LoadMetaData(dlg.FileName);
           
        }

        private void SaveMetaDataClick(object sender, RoutedEventArgs e)
        {
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.DefaultExt = ".xml";
            dlg.Filter = "XML Documents(.xml)|*.xml";
            Nullable<Boolean> result = dlg.ShowDialog();
            SaveMetaData(dlg.FileName);
        }

        private void filedropped(object sender, DragEventArgs e)
        {
            string[] files = e.Data.GetData(DataFormats.FileDrop, true) as string[];
            LoadMetaData(files[0]);
        }


    }

    public class plist : ObservableCollection<prop>
    {
        private int _pcount, _fcount, _mcount = 0;
        public int pcount { get { return _pcount; } }
        public int fcount { get { return _fcount; } }
        public int mcount { get { return _mcount; } }
        public new void Add(prop value)  // Overriding the ADD method from the base class 
        {
            if (value.propitem == "P") _pcount++;
            if (value.propitem == "F") _fcount++;
            if (value.propitem == "M") _mcount++;
            base.Add(value); //Call the original Add method 
        }
        public new void Clear() // Overriding the Clear method from the base class
        {
            this._fcount = 0;
            this._mcount = 0;
            this._pcount = 0;
            base.Clear();
        }
      
    }


    public class prop
    {
        public string propscope { get; set; }
        public string propname { get; set; }
        public string proptype { get; set; }
        public Boolean propreadonly { get; set; }
        public string propitem { get; set; }
        
        
        public prop()
        {
        }
        public prop(string __scope, string __propname, string __proptype, Boolean __propreadonly, string __propitem)
        {
            propscope = __scope;
            propname = __propname;
            proptype = __proptype;
            propreadonly = __propreadonly;
            propitem = __propitem;
            
        }
    }

    // Converter to display color based on type
    [ValueConversion(typeof(String), typeof(SolidColorBrush))]
    public class ItemtoColor : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string item = (string)value;
            SolidColorBrush returnbrush = new SolidColorBrush();
            
            if (item == "P")
                returnbrush = new SolidColorBrush(Colors.Yellow); 
            if (item == "F")
                returnbrush = new SolidColorBrush(Colors.Green); 
            if (item == "M")
                returnbrush = new SolidColorBrush(Colors.Blue); 
            return returnbrush;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return null;
        }
    }
}